﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Drawing;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Windows.Forms;
using FreeBroker.Properties;
using Generic.DataStructures;
using MRG.Controls.UI;

namespace FreeBroker
{
    public partial class BrokerMainForm : Form
    {
        public BrokerMainForm()
        {
            InitializeComponent();
        }

        private const string div = "<#§#>";

        private void BrokerMainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            BrokerMainForm.running = false;
            Settings.Default.autoUpdate = this.buttonAutoUpdate.Checked;
            int value = this.trackBarFrameSize.Value;
            Settings.Default.ThumbSizeIndex = value;
            Settings.Default.AutoUpdateMinutes = this.numUpDownAutoUpdateInterval.Value;
            Settings.Default.MainWindowPos = this.Location;
            Settings.Default.MainWindowSize = this.Size;

            // Save process list
            Settings.Default.BrokerNotations = new StringCollection();
            for (int i = 0; i < processList.Count; i++)
            {
                // Iterate ordered process numbers
                int procNumber = processList[i];
                BrokerObject b = processes[procNumber];
                Settings.Default.BrokerNotations.Add(i + div + b.Name + div + b.IdNotation + div + b.Type.Name);
            }

            Settings.Default.Save();
        }

        private void BrokerMainForm_Shown(object sender, EventArgs e)
        {
            // Load last used broker symbols
            StringCollection brokerNotations = Settings.Default.BrokerNotations;
            if (brokerNotations != null)
            {
                // Create list to order entries
                List<int> procList = new List<int>();
                Dictionary<int, string> names = new Dictionary<int, string>();
                Dictionary<int, string> notations = new Dictionary<int, string>();
                Dictionary<int, string> types = new Dictionary<int, string>();
                foreach (string item in brokerNotations)
                {
                    string[] parts = item.Split(new string[] { div }, StringSplitOptions.None);
                    if (parts.Length == 4)
                    {
                        int key = int.Parse(parts[0]);
                        procList.Add(key);
                        string name = parts[1];
                        string idNotation = parts[2];
                        string type = parts[3];
                        names.Add(key, name);
                        notations.Add(key, idNotation);
                        types.Add(key, type);
                    }
                }
                procList.Sort();
                // Create processes in the last saved order
                foreach (int item in procList)
                {
                    BrokerObject obj = new BrokerObject();
                    obj.Name = names[item];
                    obj.IdNotation = notations[item];
                    obj.Type = InformerType.FromName(types[item]);
                    CreateBrokerObserver(obj);
                }
            }

            this.trackBarFrameSize.Value = Settings.Default.ThumbSizeIndex;
            ChangeThumbSizes();
            //UpdateStarter update = new UpdateStarter();
            //update.Update(Program.info, true);

            BrokerMainForm.running = true;
            BrokerMainForm.autoUpdate = Settings.Default.autoUpdate;
            this.buttonAutoUpdate.Checked = BrokerMainForm.autoUpdate;
            if (autoUpdate)
            {
                this.toolStripStatusLabel.Text = "Nächste automatische Aktualisierung in ";
            }
            this.numUpDownAutoUpdateInterval.Value = Settings.Default.AutoUpdateMinutes;
            this.Size = Settings.Default.MainWindowSize;
            this.Location = Settings.Default.MainWindowPos;
            processManager.RunWorkerAsync();
        }

        private static bool running = false;

        private static bool autoUpdate = false;

        private Queue<int> jobQueue = new Queue<int>();

        private static AutoResetEvent locked = new AutoResetEvent(true);

        private void SetToolStripStatus(string part1, string part2)
        {
            if (statusStrip.InvokeRequired)
            {
                statusStrip.Invoke(new SetToolStripStatusDelegate(SetToolStripStatus), new object[] { part1, part2 });
                return;
            }
            if (part1 != null)
            {
                toolStripStatusLabel.Text = part1;
            }
            if (part2 != null)
            {
                toolStripStatusLabelSec.Text = part2;
            }
        }
        private delegate void SetToolStripStatusDelegate(string part1, string part2);

        private void buttonSearch_Click(object sender, EventArgs e)
        {
            SearchForm form = new SearchForm();
            DialogResult dialogResult = form.ShowDialog();
            if (dialogResult == DialogResult.OK)
            {
                ComDirectSearchResult result = form.SelectedObject;
                if (result == null)
                {
                    return;
                }
                BrokerObject brokerObj = new BrokerObject();
                brokerObj.Name = result.Name;
                brokerObj.Type = result.Type;
                brokerObj.Url = result.Url;
                brokerObj.StockMarket = result.StockMarket;
                brokerObj.Currency = result.Currency;
                brokerObj.DateTime = result.DateTime;
                brokerObj.ActualValue = result.ActualValue;
                string notation = result.Url.Substring(result.Url.IndexOf('=') + 1);
                brokerObj.IdNotation = notation;

                // Parse page for additional information
                CollectAdditionalInfo(brokerObj);

                CreateBrokerObserver(brokerObj);
            }
        }

        private void CollectAdditionalInfo(BrokerObject brokerObj)
        {
            Console.WriteLine("Collecting additional information for ID: " + brokerObj.IdNotation);
            Communication com = new Communication();
            string content = com.SendGetRequest(brokerObj.Url);
            Regex regex = CategoryRegExes.GetAdditionalInfo(brokerObj.Type);
            if (regex == null)
            {
                Console.WriteLine("No regex for additional info available, type: " + brokerObj.Type);
                return;
            }
            Match match = regex.Match(content);
            brokerObj.DateTime = ClearString(match.Groups["date"].Value);
            brokerObj.Wkn = ClearString(match.Groups["wkn"].Value);
            brokerObj.StockMarket = ClearString(match.Groups["market"].Value);
            brokerObj.Symbol = ClearString(match.Groups["symbol"].Value);
            brokerObj.Isin = ClearString(match.Groups["isin"].Value);
            brokerObj.ActualValue = ClearString(match.Groups["value"].Value);
            brokerObj.Currency = ClearString(match.Groups["currency"].Value);
            Console.WriteLine("Collecting additional information has finished.");
        }

        private string ClearString(string input)
        {
            if (input == null || input.Length == 0)
            {
                return "--";
            }
            input = Helper.UnescapeHtmlString(input.Trim());
            return input;
        }

        private void ReloadChartThumb(int procNumber)
        {
            BrokerObject brokerObj = this.processes[procNumber];
            Console.WriteLine("Locking thread for process <" + brokerObj.Name + ">...");
            locked.WaitOne(60000, true);
            Console.WriteLine("Running process <" + brokerObj.Name + ">...");
            LoadingCircle circle = GetLoadingCircle4Broker(brokerObj);
            if (circle != null)
            {
                ChangeLoadingCircleState(circle, true);
            }
            BackgroundWorker worker = brokerObj.Worker;
            while (worker.IsBusy)
            {
                worker.CancelAsync();
                Thread.Sleep(500);
            }
            worker.RunWorkerAsync(brokerObj);
        }

        private int FindProcNumber4Broker(BrokerObject obj)
        {
            if (obj != null && this.processes != null)
            {
                foreach (int procNumber in this.processes.Keys)
                {
                    if (this.processes[procNumber] == obj)
                    {
                        return procNumber;
                    }
                }
            }
            return -1;
        }

        private GroupBox GetGroupBox4Broker(BrokerObject obj)
        {
            int procNumber = FindProcNumber4Broker(obj);
            if (procNumber >= 0)
            {
                Control box = flowLayoutPanel.Controls["groupBoxChart" + procNumber];
                if (box != null)
                {
                    return (GroupBox)box;
                }
            }
            return null;
        }

        private Button GetImageButton4Broker(BrokerObject obj)
        {
            int procNumber = FindProcNumber4Broker(obj);
            if (procNumber >= 0)
            {
                Control box = flowLayoutPanel.Controls["groupBoxChart" + procNumber];
                if (box != null)
                {
                    Control imageBtn = box.Controls["buttonChart" + procNumber];
                    if (imageBtn != null)
                    {
                        return (Button)imageBtn;
                    }
                }
            }
            return null;
        }

        private LoadingCircle GetLoadingCircle4Broker(BrokerObject obj)
        {
            int procNumber = FindProcNumber4Broker(obj);
            if (procNumber >= 0)
            {
                Control box = flowLayoutPanel.Controls["groupBoxChart" + procNumber];
                if (box != null)
                {
                    Control circle = box.Controls["loadingCircle" + procNumber];
                    if (circle != null)
                    {
                        return (LoadingCircle)circle;
                    }
                }
            }
            return null;
        }

        private Label GetTitleLabel4Broker(BrokerObject obj)
        {
            int procNumber = FindProcNumber4Broker(obj);
            if (procNumber >= 0)
            {
                Control box = flowLayoutPanel.Controls["groupBoxChart" + procNumber];
                if (box != null)
                {
                    Control label = box.Controls["labelChartTitle" + procNumber];
                    if (label != null)
                    {
                        return (Label)label;
                    }
                }
            }
            return null;
        }

        private Label GetWknLabel4Broker(BrokerObject obj)
        {
            int procNumber = FindProcNumber4Broker(obj);
            if (procNumber >= 0)
            {
                Control box = flowLayoutPanel.Controls["groupBoxChart" + procNumber];
                if (box != null)
                {
                    Control label = box.Controls["labelChartWkn" + procNumber];
                    if (label != null)
                    {
                        return (Label)label;
                    }
                }
            }
            return null;
        }

        private void SetAttribs(BrokerObject brokerObj)
        {
            if (brokerObj == null)
            {
                return;
            }
            Button imageButton = GetImageButton4Broker(brokerObj);
            Label labelTitle = GetTitleLabel4Broker(brokerObj);
            Label labelWkn = GetWknLabel4Broker(brokerObj);
            LoadingCircle loadingCircle = GetLoadingCircle4Broker(brokerObj);
            if (imageButton == null || labelTitle == null || loadingCircle == null)
            {
                Console.WriteLine("ERROR: GUI control not found found.");
                return;
            }
            if (imageButton.InvokeRequired )
            {
                imageButton.Invoke(new SetAttribsDelegate(SetAttribs), new object[] { brokerObj });
                return;
            }
            if (labelTitle.InvokeRequired)
            {
                labelTitle.Invoke(new SetAttribsDelegate(SetAttribs), new object[] { brokerObj });
                return;
            }
            if (labelWkn.InvokeRequired)
            {
                labelWkn.Invoke(new SetAttribsDelegate(SetAttribs), new object[] { brokerObj });
                return;
            }
            if (loadingCircle.InvokeRequired)
            {
                loadingCircle.Invoke(new SetAttribsDelegate(SetAttribs), new object[] { brokerObj });
                return;
            }
            imageButton.BackgroundImage = brokerObj.chartThumbnail;
            imageButton.Text = "";
            labelTitle.Text = brokerObj.GetUnescapedName();
            labelWkn.Text = "WKN: " + brokerObj.Wkn;
            BuildChartToolTip(imageButton, brokerObj);
            loadingCircle.FadeOut();
        }
        private delegate void SetAttribsDelegate(BrokerObject broker);

        private void ChangeLoadingCircleState(LoadingCircle circle, bool start)
        {
            if (circle.InvokeRequired)
            {
                circle.Invoke(new ChangeLoadingCircleStateDelegate(ChangeLoadingCircleState), new object[] { circle, start });
                return;
            }
            if (start)
            {
                circle.FadeIn();
            }
            else
            {
                circle.FadeOut();
            }
        }
        private delegate void ChangeLoadingCircleStateDelegate(LoadingCircle circle, bool start);

        private void buttonInfoPageParse_Click(object sender, EventArgs e)
        {
            StreamReader sr = new StreamReader(@"c:\test.html");
            string content = sr.ReadToEnd();
            Regex regex = new Regex("<h1>(.+?)</h1>(.*?[\r\n]*.*?)*?WKN&nbsp;<strong>(.*?)</strong>(.*?[\r\n]*.*?)*?ISIN&nbsp;<strong>(.*?)</strong>(.*?[\r\n]*.*?)*?Symbol&nbsp;<strong>(.*?)</strong>(.*?[\r\n]*.*?)*?Gattung:(.*?[\r\n]*.*?)*?<td.*?>(.+?)</td(.*?[\r\n]*.*?)*?Land:(.*?[\r\n]*.*?)*?<td>(.*?)</td");
            MatchCollection col = regex.Matches(content);
            foreach (Match match in col)
            {
                Console.WriteLine("-------------------------------------");
                Console.WriteLine("Name: " + match.Groups[1].Value);
                Console.WriteLine("ISIN: " + match.Groups[5].Value);
                Console.WriteLine(" WKN: " + match.Groups[3].Value);
                Console.WriteLine("Symbol: " + match.Groups[7].Value);
                Console.WriteLine("Gattung: " + match.Groups[10].Value);
                Console.WriteLine("Land: " + match.Groups[13].Value);
            }
            Console.WriteLine();
        }

        private void buttonAutoUpdate_Click(object sender, EventArgs e)
        {
            RadioButton but = (RadioButton)sender;
            BrokerMainForm.autoUpdate = !but.Checked;
            but.Checked = !but.Checked;
            this.numUpDownAutoUpdateInterval.Enabled = but.Checked;
            if (but.Checked)
            {
                this.toolStripStatusLabel.Text = "Nächste automatische Aktualisierung in ";
                this.toolStripStatusLabelSec.Text = this.numUpDownAutoUpdateInterval.Value.ToString() + " Sekunden";
            }
            else
            {
                this.toolStripStatusLabel.Text = "Die automatische Aktualisierung wurde deaktiviert.";
                this.toolStripStatusLabelSec.Text = "";
            }
        }

        private Size chartThumbSize = new Size(157, 129);
        private Dictionary<int, BrokerObject> processes = new Dictionary<int, BrokerObject>();
        public Dictionary<int, BrokerObject> Processes
        {
            get { return processes; }
        }

        private List<int> processList = new List<int>();

        private void MoveProcess(int oldIndex, int newIndex)
        {
            if (oldIndex < 0 || oldIndex > this.processList.Count)
            {
                Console.WriteLine("Old index is out of range.");
                return;
            }
            if (newIndex < 0 || newIndex > this.processList.Count)
            {
                Console.WriteLine("New index is out of range.");
                return;
            }
            int processNumber = this.processList[oldIndex];
            this.processList.RemoveAt(oldIndex);
            this.processList.Insert(newIndex, processNumber);
        }

        private int procCounter = 0;

        private void CreateBrokerObserver(BrokerObject brokerObj)
        {
            // 
            // groupBoxChart
            //
            GroupBox groupBoxChart = new GroupBox();
            groupBoxChart.Location = new Point(3, 3);
            groupBoxChart.Name = "groupBoxChart" + procCounter;
            groupBoxChart.Text = brokerObj.Type.Name;
            groupBoxChart.Size = new Size(170, 184);
            groupBoxChart.TabIndex = 0;
            groupBoxChart.TabStop = false;
            groupBoxChart.Tag = procCounter;
            groupBoxChart.AllowDrop = true;
            groupBoxChart.MouseDown += new MouseEventHandler(groupBoxChart_MouseDown);
            groupBoxChart.DragDrop += new DragEventHandler(groupBoxChartOnDragDrop);
            groupBoxChart.DragEnter += new DragEventHandler(groupBoxChartOnDragEnter);
            groupBoxChart.MouseEnter += new EventHandler(groupBoxChart_MouseEnter);
            groupBoxChart.MouseLeave += new EventHandler(groupBoxChart_MouseLeave);
            groupBoxChart.ContextMenuStrip = this.contextMenuGroups;
            // 
            // labelChartTitle
            // 
            Label labelChartTitle = new Label();
            labelChartTitle.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
            labelChartTitle.Location = new Point(20, 17);
            labelChartTitle.Name = "labelChartTitle" + procCounter;
            labelChartTitle.Size = new Size(145, 13);
            labelChartTitle.TabIndex = 21;
            labelChartTitle.TextAlign = ContentAlignment.MiddleLeft;
            labelChartTitle.Text = brokerObj.GetUnescapedName();
            labelChartTitle.MouseDown += new MouseEventHandler(groupBoxChart_MouseDown);
            labelChartTitle.MouseEnter += new EventHandler(groupBoxChart_MouseEnter);
            labelChartTitle.MouseLeave += new EventHandler(groupBoxChart_MouseLeave);
            labelChartTitle.ContextMenuStrip = this.contextMenuGroups;
            // 
            // labelChartWkn
            // 
            Label labelChartWkn = new Label();
            labelChartWkn.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
            labelChartWkn.Location = new Point(20, 32);
            labelChartWkn.Name = "labelChartWkn" + procCounter;
            labelChartWkn.Size = new Size(145, 13);
            labelChartWkn.TabIndex = 22;
            labelChartWkn.TextAlign = ContentAlignment.MiddleLeft;
            labelChartWkn.Text = "WKN: " + brokerObj.Wkn;
            labelChartWkn.MouseDown += new MouseEventHandler(groupBoxChart_MouseDown);
            labelChartWkn.MouseEnter += new EventHandler(groupBoxChart_MouseEnter);
            labelChartWkn.MouseLeave += new EventHandler(groupBoxChart_MouseLeave);
            labelChartWkn.ContextMenuStrip = this.contextMenuGroups;
            // 
            // buttonChart
            // 
            Button buttonChart = new Button();
            buttonChart.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
            buttonChart.Location = new Point(6, 48);
            buttonChart.Name = "buttonChart" + procCounter;
            buttonChart.Size = new Size(157, 129);
            buttonChart.TabIndex = 2;
            buttonChart.TabStop = false;
            buttonChart.BackgroundImageLayout = ImageLayout.Stretch;
            buttonChart.Text = "Wird geladen...";
            buttonChart.Click += new EventHandler(buttonChart_Click);
            buttonChart.ContextMenuStrip = this.contextMenuGroups;
            //
            LoadingCircle loadingCircle = new LoadingCircle();
            loadingCircle.Active = false;
            loadingCircle.Color = Color.LightBlue;
            loadingCircle.FadeInSpeed = LoadingCircle.FadeSpeeds.Fast;
            loadingCircle.FadeOutSpeed = LoadingCircle.FadeSpeeds.Fast;
            loadingCircle.InnerCircleRadius = 5;
            loadingCircle.Location = new Point(3, 17);
            loadingCircle.Name = "loadingCircle" + procCounter;
            loadingCircle.NumberSpoke = 18;
            loadingCircle.OuterCircleRadius = 7;
            loadingCircle.RotationSpeed = 60;
            loadingCircle.Size = new Size(17, 18);
            loadingCircle.SpokeThickness = 3;
            loadingCircle.Visible = false;
            loadingCircle.BringToFront();
            //
            groupBoxChart.Controls.Add(labelChartTitle);
            groupBoxChart.Controls.Add(labelChartWkn);
            groupBoxChart.Controls.Add(buttonChart);
            groupBoxChart.Controls.Add(loadingCircle);
            groupBoxChart.Size = new Size(chartThumbSize.Width + 20, chartThumbSize.Height + 50);
            string helpText = "Zum verschieben einfach Maustaste gedrückt halten,\nüber einen anderen Prozess ziehen und loslassen.";
            this.toolTip.SetToolTip(groupBoxChart, helpText);
            this.toolTip.SetToolTip(labelChartTitle, helpText);
            //
            this.flowLayoutPanel.Controls.Add(groupBoxChart);
            //
            // Create background thread
            //
            BackgroundWorker worker = new BackgroundWorker();
            worker.WorkerSupportsCancellation = true;
            worker.DoWork += new DoWorkEventHandler(backgroundWorker_DoWork);
            worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker_RunWorkerCompleted);
            brokerObj.Worker = worker;
            //
            // tool tip
            //
            BuildChartToolTip(buttonChart, brokerObj);
            //
            this.processes.Add(this.procCounter, brokerObj);
            this.processList.Add(this.procCounter);
            //
            // Start process
            this.jobQueue.Enqueue(this.procCounter);
            this.procCounter++;
        }

        private void BuildChartToolTip(Button buttonChart, BrokerObject brokerObj)
        {
            StringBuilder builder = new StringBuilder();
            builder.Append("Typ:  ");
            builder.AppendLine(brokerObj.Type.Name);
            builder.Append("Name:  ");
            builder.AppendLine(Helper.UnescapeHtmlString(brokerObj.Name));

            if (brokerObj.Type.Category != InformerType.CAT_BOND &&
                brokerObj.Type.Category != InformerType.CAT_FUND)
            {
                builder.Append("Symbol:  ");
                builder.AppendLine(brokerObj.Symbol);
            }
            if (brokerObj.Type.Category != InformerType.CAT_CURRENCY)
            {
                builder.Append("ISIN:  ");
                builder.AppendLine(brokerObj.Isin);
            }
            if (brokerObj.Type.Category != InformerType.CAT_CURRENCY)
            {
                builder.Append("WKN:  ");
                builder.AppendLine(brokerObj.Wkn);
            }
            builder.Append("Börse:  ");
            builder.AppendLine(brokerObj.StockMarket);
            if (brokerObj.Type.Category != InformerType.CAT_BROKER &&
                brokerObj.Type.Category != InformerType.CAT_CURRENCY)
            {
                builder.Append("Währung:  ");
                builder.AppendLine(brokerObj.Currency);
            }
            builder.Append("Aktuell:  ");
            builder.AppendLine(brokerObj.ActualValue);
            this.toolTip.SetToolTip(buttonChart, builder.ToString());
        }

        void buttonChart_Click(object sender, EventArgs e)
        {
            Control cntl = (Control)sender;
            if (cntl.Parent != null && cntl.Parent.GetType() == typeof(GroupBox))
            {
                int index = (int)cntl.Parent.Tag;
                if (index != -1 && this.processes.ContainsKey(index))
                {
                    DetailView view = new DetailView(this, index);
                    view.Show();
                }
            }
        }

        private void toolStripItemDelete_Click(object sender, EventArgs e)
        {
            ToolStripMenuItem menuItem = (ToolStripMenuItem)sender;
            ContextMenuStrip menuStrip = (ContextMenuStrip)menuItem.Owner;
            GroupBox box = null;
            if (menuStrip.SourceControl.GetType() == typeof(GroupBox))
            {
                box = (GroupBox)menuStrip.SourceControl;
            }
            else
            {
                box = (GroupBox)menuStrip.SourceControl.Parent;
            }
            if (box != null)
            {
                int number = (int)box.Tag;
                flowLayoutPanel.Controls.Remove(box);
                this.processes.Remove(number);
                this.processList.Remove(number);
            }
        }


        private void trackBarFrameSize_Scroll(object sender, EventArgs e)
        {
            ChangeThumbSizes();
        }

        private void toolStripItemRefresh_Click(object sender, EventArgs e)
        {
            ToolStripMenuItem menuItem = (ToolStripMenuItem)sender;
            ContextMenuStrip menuStrip = (ContextMenuStrip)menuItem.Owner;
            GroupBox box = null;
            if (menuStrip.SourceControl.GetType() == typeof(GroupBox))
            {
                box = (GroupBox)menuStrip.SourceControl;
            }
            else
            {
                box = (GroupBox)menuStrip.SourceControl.Parent;
            }
            if (box != null)
            {
                int index = (int)box.Tag;
                if (index != -1)
                {
                    this.jobQueue.Enqueue(index);
                }
            }
        }

        private void flowLayoutPanel_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            buttonSearch_Click(null, null);
        }

        private void toolStripItemDetail_Click(object sender, EventArgs e)
        {
            ToolStripMenuItem menuItem = (ToolStripMenuItem)sender;
            ContextMenuStrip menuStrip = (ContextMenuStrip)menuItem.Owner;
            GroupBox box = null;
            if (menuStrip.SourceControl.GetType() == typeof(GroupBox))
            {
                box = (GroupBox)menuStrip.SourceControl;
            }
            else
            {
                box = (GroupBox)menuStrip.SourceControl.Parent;
            }
            if (box != null)
            {
                int index = (int)box.Tag;
                if (index != -1 && this.processes.ContainsKey(index))
                {
                    DetailView view = new DetailView(this,index);
                    view.Show();
                }
            }
        }

        private SynchronizedList<int> processQueue = new SynchronizedList<int>();

        private void EnqueueProcess(int index, bool highPriority)
        {
            if (index >= 0)
            {
                if (processQueue.Contains(index))
                {
                    if (highPriority)
                    {
                        processQueue.Remove(index);
                        processQueue.Insert(0, index);
                    }
                    else
                    {
                        // Do nothing, item is already in list
                    }
                }
                else
                {
                    if (highPriority)
                    {
                        processQueue.Insert(0, index);
                    }
                    else
                    {
                        processQueue.Add(index);
                    }
                }
            }
        }

        private void timer_Tick(object sender, EventArgs e)
        {
            foreach (int index in this.processes.Keys)
            {
                EnqueueProcess(index, false);
            }
        }

        private void numericUpDown_ValueChanged(object sender, EventArgs e)
        {
            int minutes = (int)this.numUpDownAutoUpdateInterval.Value;
            int seconds = minutes * 60;
            int milliseconds = seconds * 1000;
            this.timer.Stop();
            this.timer.Interval = milliseconds;
            this.timer.Start();
        }

    }
}
